/* -------------------------------------------------------------------------
 *  This file is part of the Cantian project.
 * Copyright (c) 2024 Huawei Technologies Co.,Ltd.
 *
 * Cantian is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *          http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * -------------------------------------------------------------------------
 *
 * dsw_message.h
 *
 *
 * IDENTIFICATION
 * src/tse/message_queue/dsw_message.h
 *
 * -------------------------------------------------------------------------
 */

#ifndef dsw_message_pub_h__
#define dsw_message_pub_h__

#include <semaphore.h>
#include "dsw_typedef.h"
#include "dsw_list.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cpluscplus */

#pragma pack(1)


#define SERVER_PROC_ID 0
#define  SERVER_REGISTER_PROC_ID 1
#define CLIENT_PROC_ID 1


typedef struct {
    uint32_t type; /* Data type */
    uint32_t length;
} dsw_message_segment_desc_t;

#define DSW_MESSAGE_SEGMENT_NUM_MAX (512) // TODO: too long, rename


typedef struct token_latency_timestamp_s {
    uint16_t start_time;
    uint16_t latency;
} token_latency_timestamp_t;

/* reserved for updating
 * 1. detect msg use 6 bytes for apm lids
 * 2. unhealthy used the first 5 bytes, and negotiation used 6th byte
 * 3. ǰ���#pragma pack(1)��֤���ڴ�һ�ֽڶ���
 */
typedef union message_head_reserved_s {
    uint8_t reserved[12];

    /* clientģ��:
     * update map when IOView is changed.
     * delete_all_osd_in_pool 1:ɾ������������osd��0:ɾ��ָ��osd
     */
    struct update_map_in_del_pool_s {
        uint32_t osd_id;
        uint8_t delete_all_osd_in_pool;
    } update_map_in_del_pool;

    uint16_t pool_id; // client ģ��
    uint8_t io_type;  // vbp/kvs-client�ж��Ƿ�˫��IO

    struct token_latency_s {
        uint8_t padding[6];                                 // padding for unhealthy_and_negoation
        token_latency_timestamp_t token_latency_timestamp; // rsmʹ��
    } token_latency;
} message_head_reserved_t;

/**
 * @ingroup Message
 * messageʱ����׶ε㣺���н׶ε㡣
 */
typedef struct {
    sem_t sem;
    uint32_t magic;
    uint32_t version;
    uint64_t request_id; /* Request ID */
    uint32_t src_nid;    /* Source node ID */
    uint32_t dst_nid;    /* Destination node ID */
    uint8_t net_point;   /* Type of net point */
    uint8_t src_mid;
    uint8_t dst_mid;
    uint32_t cmd_type;  /* Command type */
    uint16_t slice_id;  /* Message slice ID */
    uint16_t priority;  /* Message priority */
    uint16_t handle_id; /* IO trace handle ID */
    uint16_t seg_num;
    dsw_message_segment_desc_t seg_desc[DSW_MESSAGE_SEGMENT_NUM_MAX];
    uint32_t crc;    /* crc of the msg */
    uint64_t try_id; /* try id */

    /* reserved for updating
     * 1. detect msg use 6 bytes for apm lids
     * 2. unhealthy used the first 5 bytes, and negotiation used 6th byte
     */
    message_head_reserved_t reserved_u;
    uint32_t head_crc; /* crc of msg head */
} dsw_message_head_t;

/*
 * Definition of message block
 *
 * A whole message block mainly cotains a message head and at most four message data. Meanwhile, the node which creates
 * the message block should record time stamp for the node (Notice: the time stamp is a 64 bits value generated by local
 * tick generator, and is only valid locally) The Time stamp will been initialized to be DSW_MESSAGE_TS_NORMAL as
 * default. If DSW_MESSAGE_TS_DROPED, the message will been discarded directly by net module.
 */
typedef struct {
    dsw_message_head_t head;
    void *seg_buf[DSW_MESSAGE_SEGMENT_NUM_MAX];
    uint64_t ts; /* Time stamp */
    uint32_t seg_buf_crc;
    list_head_t msg_node;
} dsw_message_block_t;

#ifdef __arm__
#pragma pack(0)
#else
#pragma pack()
#endif

#ifdef __cplusplus
}
#endif /* __cpluscplus */
#endif // dsw_message_pub_h__
